home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib43 / mntlib / open.c < prev    next >
C/C++ Source or Header  |  1994-02-14  |  5KB  |  211 lines

  1. /* based upon Dale Schumacher's dLibs library */
  2. /* extensively modified by ers */
  3.  
  4. #include <compiler.h>
  5. #include <osbind.h>
  6. #include <mintbind.h>
  7. #include <limits.h>
  8. #include <fcntl.h>
  9. #include <ioctl.h>
  10. #include <errno.h>
  11. #include <unistd.h>
  12. #include <stdarg.h>
  13. #include <stat.h>
  14. #include "lib.h"
  15.  
  16. /*
  17.  * the MiNT kernel uses 0x08 for O_APPEND. For
  18.  * backwards compatibility with old .o files,
  19.  * we leave the definition in fcntl.h the same,
  20.  * but adjust the file masks here.
  21.  */
  22.  
  23. static int __umask = -1;
  24. extern int __mint;
  25.  
  26. static void _get_umask __PROTO((void));
  27.  
  28. /*
  29.  * function to set the initial value of __umask
  30.  */
  31.  
  32. static void
  33. _get_umask()
  34. {
  35.     if (__mint < 9) {
  36.         __umask = 0;
  37.     } else {
  38.         __umask = Pumask(0);
  39.         (void) Pumask(__umask);
  40.     }
  41. }
  42.  
  43. /* NOTE: we assume here that every compiler that can handle __PROTO
  44.  *       is __STDC__ and can handle the >>...<< ellipsis
  45.  *       (see also unistd.h)
  46.  */
  47.  
  48. #ifdef __STDC__
  49. int open(const char *_filename, int iomode, ...)
  50. #else
  51. int open(_filename, iomode, pmode)
  52.     const char *_filename;
  53.     int iomode;
  54.     unsigned pmode;
  55. #endif
  56. {
  57.     int rv;
  58.     int modemask;            /* which bits get passed to the OS? */
  59.     char filename[PATH_MAX];
  60.     long fcbuf;            /* a temporary buffer for Fcntl */
  61.  
  62. #ifdef __STDC__
  63.     unsigned pmode;
  64.     va_list argp;
  65.     va_start(argp, iomode);
  66.     pmode = va_arg(argp, unsigned int);
  67.     va_end(argp);
  68. #endif
  69.  
  70.     _unx2dos(_filename, filename);
  71.  
  72. /* use the umask() setting to get the right permissions */
  73.     if (__umask == -1)
  74.         _get_umask();
  75.     pmode &= ~__umask;
  76.  
  77. /* set the file access modes correctly */
  78.     iomode = iomode & ~O_SHMODE;
  79.  
  80.     if (__mint >= 9) {
  81.         modemask = O_ACCMODE | O_SHMODE | O_SYNC | O_NDELAY 
  82.                            | O_CREAT | O_TRUNC | O_EXCL;
  83.         iomode |= O_DENYNONE;
  84.         if (__mint >= 96) {
  85.             modemask |= _REALO_APPEND;
  86.             if (iomode & O_APPEND)
  87.                 iomode |= _REALO_APPEND;
  88.         }
  89.     } else {
  90.         modemask = O_ACCMODE;
  91.     }
  92.  
  93.     if(Fattrib(filename, 0, 0) >= 0)        /* file exists */
  94.     {
  95.         if((iomode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
  96.             errno = EEXIST;
  97.             return -1;
  98.         }
  99.         rv = (int)Fopen(filename,iomode & modemask);
  100.         if ((iomode & ~modemask & O_TRUNC) && (rv >= 0)) {
  101.             /* Give up if the mode flags conflict */
  102.             if (iomode & O_RDONLY) {
  103.                 (void)Fclose(rv);
  104.                 errno = EACCES;
  105.                 return -1;
  106.             }
  107.             /* Try the FTRUNCATE first.  If it fails, have GEMDOS
  108.                truncate it, then reopen with the correct modes.
  109.             */
  110.             fcbuf = 0L;
  111.             if ((__mint <= 90)
  112.                 || (Fcntl(rv, (long) &fcbuf, FTRUNCATE) < 0)) {
  113.                 (void)Fclose(rv);
  114.                 rv = (int)Fcreate(filename, 0x00);
  115.                 if (rv < 0) {
  116.                     errno = -rv;
  117.                     return -1;
  118.                 }
  119.                 (void)Fclose(rv);
  120.                 rv = (int)Fopen(filename,iomode & modemask);
  121.             }
  122.         }
  123.     }
  124.     else                    /* file doesn't exist */
  125.     {
  126.         if(iomode & O_CREAT) {
  127.             if (__mint >= 9)
  128.               rv = (int) Fopen (filename, iomode & modemask);
  129.             else {
  130.                 rv = (int)Fcreate(filename, 0x00);
  131.                 if (rv >= 0) {
  132.                 (void)Fclose(rv);
  133.                 rv = (int)Fopen(filename,iomode & modemask);
  134.                 }
  135.             }
  136.             if (rv >= 0 && __mint >= 9)
  137.                 (void)Fchmod(filename, pmode);
  138.         }
  139.         else
  140.             rv = -ENOENT;
  141.     }
  142.  
  143.     if(rv < (__SMALLEST_VALID_HANDLE)) {
  144.         errno = -rv;
  145.         return __SMALLEST_VALID_HANDLE - 1;
  146.     }
  147.     if (__mint) {
  148.         /* Relocate the handle to the lowest positive numbered handle
  149.            available
  150.         */
  151.         fcbuf = Fcntl(rv, (long) 0, F_DUPFD);
  152.         if (fcbuf >= 0) {
  153.           if (fcbuf < rv) {
  154.         (void) Fclose(rv);
  155.             rv = (int) fcbuf;
  156.           } else {
  157.             (void) Fclose((int) fcbuf);
  158.           }
  159.         }
  160.             /* clear the close-on-exec flag */
  161.         fcbuf = (long)Fcntl(rv, (long)0, F_GETFD);
  162.         (void)Fcntl(rv, fcbuf & ~FD_CLOEXEC, F_SETFD);
  163.     }
  164.     if ((iomode & O_APPEND) && !(modemask & _REALO_APPEND))
  165.         (void)Fseek(0L, rv, SEEK_END);
  166.  
  167.      /* Important side effect:  isatty(rv) sets up flags under TOS */
  168.     if (isatty(rv) && (!(iomode & O_NOCTTY)) && (!(isatty(-1)))) {
  169.           /* If the process is a session leader with no controlling tty,
  170.              and the tty that was opened is not already the controlling
  171.              tty of another process, the tty becomes the controlling tty
  172.              of the process.  Note that MiNT has no concept of a session
  173.              leader so we really only check that it is a process group
  174.              leader.
  175.           */
  176.       if ((!__mint) 
  177.               || ((Pgetpgrp() == Pgetpid())
  178.                   && (Fcntl(rv, &fcbuf, TIOCGPGRP) >= 0)
  179.                   && (fcbuf == 0))) {
  180.             (void) Fforce(-1, rv);    /* new controlling tty */
  181.             __open_stat[__OPEN_INDEX(-1)] = __open_stat[__OPEN_INDEX(rv)];
  182.       }
  183.     }
  184.     
  185.     return(rv);
  186. }
  187.  
  188. int
  189. creat(name, mode)
  190.     const char *name;
  191.     unsigned   mode;
  192. {
  193.     return open(name, O_WRONLY|O_CREAT|O_TRUNC, mode);
  194. }
  195.  
  196. /* umask -- change default file creation mask */
  197.  
  198. int umask(complmode)
  199.        int complmode;
  200. {
  201.     int old_umask;
  202.  
  203.     if (__umask == -1)
  204.         _get_umask();
  205.     old_umask = __umask;
  206.     __umask = complmode;
  207.     if (__mint >= 9)
  208.         return Pumask(complmode);
  209.     return old_umask;
  210. }
  211.